(function () {
    'use strict';

    window.employees = {
        makeTeam: function (employeeTable) {
            var pub, priv;

            priv = {
                employees: [],
                employeeService: '/EmployeeService/api/employee',
                employeeTable: $(employeeTable).find('tbody'),
                templates: {
                    employeeTemplate: _.template($('#template-employee').text()),
                    errorTemplate: _.template($('#template-error').text())
                },
                updateForm: $('form#givePayrise'),
                init: function () {
                    priv.updateForm.find('button[type=submit]').attr('disabled', false);

                    priv.addEventHandlers();
                    priv.fetchEmployees();
                },
                addEventHandlers: function () {
                    priv.updateForm.on('submit', function (event) {
                        var id = Number(priv.updateForm.find('select[name=Id]').val()),
                            updatedEmployee = _.clone(pub.getEmployeeById(id)),
                            updateButton = priv.updateForm.find('button[type=submit]').attr('disabled', true);

                        event.preventDefault();

                        updatedEmployee.MarketPercentageMultiplier = priv.updateForm.find('select[name=marketMultiplier]').val();

                        jQuery.ajax(priv.employeeService + '/' + id, {
                            type: 'POST',
                            data: updatedEmployee
                        }).done(function (data) {
                            priv.updateEmployee(data);
                            priv.renderEmployees();
                            updateButton.attr('disabled', false);
                        });
                    });
                },
                updateEmployee: function (updatedEmployee) {
                    _.every(priv.employees, function (employee, i) {
                        if (employee.Id === updatedEmployee.Id) {
                            priv.employees[i] = updatedEmployee;
                            return false;
                        }

                        return true;
                    });
                },
                fetchEmployees: function () {
                    jQuery.ajax(priv.employeeService)
                        .done(function (data) {
                            priv.employees = data;
                            priv.renderEmployees();
                            priv.updateEmployeeSelectBox();
                        })
                        .fail(function (data) {
                            priv.renderError(data.responseText);
                        });
                },
                renderEmployees: function () {
                    priv.employeeTable.empty();

                    _.each(priv.employees, function (employee) {
                        priv.renderEmployee(employee);
                    });
                },
                renderEmployee: function (employee) {
                    priv.employeeTable.append(priv.templates.employeeTemplate({
                        id: employee.Id,
                        name: pub.getEmployeeName(employee),
                        level: employee.Level,
                        marketMultiplier: employee.MarketPercentageMultiplier,
                        salary: pub.getEmployeeSalary(employee)
                    }));
                },
                renderError: function (errorMessage) {
                    priv.employeeTable.append(priv.templates.errorTemplate({
                        errorMessage: errorMessage
                    }));

                    priv.updateForm.hide();
                },
                updateEmployeeSelectBox: function () {
                    var select = $('form#givePayrise select[name=Id]').empty();

                    _.each(priv.employees, function (employee) {
                        select.append(
                            $('<option />', {
                                value: employee.Id,
                                text: pub.getEmployeeName(employee)
                            })
                        );
                    });
                }
            };

            pub = {
                getEmployeeById: function (id) {
                    return _.find(priv.employees, function (employee) {
                        if (employee.Id === id) {
                            return employee;
                        }
                    });
                },
                getEmployeeName: function (employee) {
                    return employee.GivenName.charAt(0) + '. ' + employee.Surname;
                },
                getEmployeeSalary: function (employee) {
                    if (!employee) {
                        throw 'invalid argument';
                    }

                    return '£' + employee.Salary;
                }
            };

            priv.init();

            return pub;
        }
    };
}());